package local.blueheart.data.springdatademo.domino;

import local.blueheart.data.springdatademo.domain.archive.ArchiveData;
import local.blueheart.data.springdatademo.domain.archive.ArchiveIndexData;
import local.blueheart.data.springdatademo.domain.archive.DocCompositedId;
import local.blueheart.data.springdatademo.domain.config.ItemDO;
import local.blueheart.data.springdatademo.exception.DominoException;
import local.blueheart.data.springdatademo.exception.DominoExceptionEnum;
import local.blueheart.data.springdatademo.util.StringUtil;
import lotus.domino.Document;
import lotus.domino.EmbeddedObject;
import lotus.domino.NotesException;
import lotus.domino.Session;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.URIBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;

public class DDocumentHelper {

    private static final Logger LOGGER = LoggerFactory.getLogger(DDocumentHelper.class);

    public static ArchiveData getArchiveData(DDocument dDocument, List<ItemDO> itemDOList) throws DominoException {
        ArchiveData archiveData = new ArchiveData();
        for (ItemDO itemDO : itemDOList) {
            try {
                String fieldName = itemDO.getAlias().toLowerCase();
                String docFieldName;
                String fieldValue;
                if (fieldName.equals("id")) {
                    //是ID直接取文档ID的值
                    fieldValue = getDocuemntId(dDocument);
                }else{
                    //不是id字段，取appField的配置
                    docFieldName = itemDO.getAppField();
                    if(docFieldName==null || docFieldName.isEmpty()){
                        //没有设置appField说明是后面程序计算出来的
                        continue;
                    }else{
                        if(docFieldName.indexOf("+")!=-1){
                            //多字段组合分拆取值
                            Set<String> values = new HashSet<String>();
                            String[] docFieldNames = docFieldName.split("\\+");
                            for(String f:docFieldNames){
                                values.add(fieldName.equals("users")?getNameItemValue(dDocument, f):getItemValue(dDocument,f));
                            }
                            fieldValue = StringUtil.join(values,",");
                        }else {
                            //单字段直接取值
                            if(fieldName.equals("users") || fieldName.equals("creator")) {
                                fieldValue = getNameItemValue(dDocument, docFieldName);
                            }else{
                                fieldValue = getItemValue(dDocument, docFieldName);
                            }
                        }
                    }


                }
                //设置值
                setItemValue(archiveData,fieldName,fieldValue);
            } catch (NotesException ne) {
                LOGGER.error("设置文档值出错",ne);
                throw new DominoException(ne,DominoExceptionEnum.CREATE_ARCH_DATA_ERR);
            }
        }
        return archiveData;
    }

    private static void setItemValue(ArchiveData archiveData,String fieldName,String value){
        if(fieldName.equals("users")){
            archiveData.setUsers(value);
        }else if(fieldName.equals("id")){
            archiveData.setDocId(value);
        }else if(fieldName.equals("uoles")){
            archiveData.setRoles(value);
        }else if(fieldName.equals("url")){
            archiveData.setUrl(value);
        }else if(fieldName.equals("content")){
            archiveData.setContent(value);
        }else if(fieldName.equals("title")){
            archiveData.setTitle(value);
        }else if(fieldName.equals("creator")){
            archiveData.setCreator(value);
        }else if(fieldName.equals("fileno")){
            archiveData.setFileNo(value);
        }
    }

    private static String join(String join,List<?> listStr){
        StringBuffer sb=new StringBuffer();
        for(int i=0,len =listStr.size();i<len;i++){
            if(i==(len-1)){
                sb.append(listStr.get(i));
            }else{
                sb.append(listStr.get(i)).append(join);
            }
        }
        return sb.toString();
    }

    public static void updateDDocumentStatus(DDocument dDocument,String item,String statusValue) throws DominoException {
        try {
            Document document = getDocument(dDocument);
            document.replaceItemValue(item, statusValue);
            document.save(true);
        }catch (NotesException ne){
            LOGGER.error("更新文档状态错误",ne);
            throw new DominoException(ne, DominoExceptionEnum.GET_UPD_DOC_ERR);
        }
    }


    public static ArchiveIndexData getArchiveIndexData(DDocument dDocument) throws DominoException {
        ArchiveIndexData archiveIndexData = new ArchiveIndexData();
//        AFMAINDOCUMENTFILEPATHRP	2018/11/28 11:52:04 P	TEXT	1	lib/fsarchive/fsarchivestore_B5T9QH.nsf
//        AFMAINDOCUMENTSERVERRP	2018/11/28 11:52:04 P	TEXT	1	CN=archive01.jx.chinamobile.com/O=jxmobile
//        AFMAINDOCUMENTUNIVERSALIDRP	2018/11/28 11:52:04 P	TEXT	1	E2DAAD905215E1CD48258353005728B4
        try {

            archiveIndexData.setCompany(getItemValue(dDocument, "company"));
            archiveIndexData.setDepartment(getItemValue(dDocument, "department"));
            archiveIndexData.setDocId(getDocuemntId(dDocument));
            archiveIndexData.setMainDocumentServer(StringUtil.formatServerName(getItemValue(dDocument, "AFMAINDOCUMENTSERVERRP"),"/O=jxmobile"));
            archiveIndexData.setSerialWord(getItemValue(dDocument, "FSSERIALWORDWP"));
            archiveIndexData.setProccessName(getItemValue(dDocument, "ProcessName"));
            archiveIndexData.setProccessNameShow(getItemValue(dDocument, "processnameshow"));
            archiveIndexData.setSubject(getItemValue(dDocument, "FLSUBJECTOS"));
            archiveIndexData.setStatus("0");
            return archiveIndexData;
        }catch (NotesException ne){
            LOGGER.error("创建archiveIndexData失败",ne);
            throw new DominoException(ne,DominoExceptionEnum.CREATE_ARCH_INDEX_DATA_ERR);
        }
    }

    public static DocCompositedId getArchiveIndexId(DDocument dDocument) throws DominoException {
        DocCompositedId docCompositedId = new DocCompositedId();
        docCompositedId.setDbPath(StringUtil.formatDbPathName(getItemValue(dDocument, "AFMAINDOCUMENTFILEPATHRP")));
        docCompositedId.setDocUniversalId(getItemValue(dDocument, "AFMAINDOCUMENTUNIVERSALIDRP"));
        return docCompositedId;
    }


    private static String getDocuemntId(DDocument dDocument) throws NotesException {
            Document document = getDocument(dDocument);
            if(document!=null) {
                return document.getUniversalID();
            }else {
                return "";
            }
    }

    private static String getNameItemValue(DDocument dDocument,String itemName) throws DominoException{
        try {
            Document document = getDocument(dDocument);
            Vector<?> v;
            if (document != null) {
                v = document.getItemValue(itemName);
                return StringUtil.evaluationJoin(v,new String[]{"OU=","CN="},"/",",");
            } else {
                return "";
            }
        }catch (NotesException ne){
            LOGGER.error("获取ITEM值出错",ne);
            throw new DominoException(ne,DominoExceptionEnum.GET_ITEM_VAL_ERROR);
        }
    }


    private static String getItemValue(DDocument dDocument,String itemName) throws DominoException {
        try {
            Document document = getDocument(dDocument);
            Vector<?> v;
            if (document != null) {
                v = document.getItemValue(itemName);
                return StringUtil.join(v,",");
            } else {
                return "";
            }
        }catch (NotesException ne){
            LOGGER.error("获取ITEM值出错",ne);
            throw new DominoException(ne,DominoExceptionEnum.GET_ITEM_VAL_ERROR);
        }
    }

    public static Document getDocument(DDocument dDocument){
        if(dDocument.getBase()!=null) {
            return (Document) dDocument.getBase();
        }else {
            return null;
        }
    }


    /**
     * 存储附件到本地
     * @param dDocument
     * @param basePath
     * @param relativePath
     * @return
     */
    public static String[] saveAttachmentToLocal(DSession dSession,DDocument dDocument, String basePath,String relativePath) {
        List<String> filePaths = new ArrayList<>();
        try {
            Session session = (Session) dSession.getBase();
            Document document = getDocument(dDocument);
            String filePath = getFilePath(basePath,relativePath,document.getUniversalID());
            Vector<String> attchmentNames = session.evaluate("@Trim(@Replace(@AttachmentNames;FileTextName:HTMLFileName;\"\"))", document);
            for(String fileName:attchmentNames){
                EmbeddedObject attachment = document.getAttachment(fileName);
                String myFilePath = filePath+"/"+fileName;
                attachment.extractFile(myFilePath);
                filePaths.add(myFilePath);
            }

        }catch (NotesException ne){
            LOGGER.error("导出附件出错",ne);
        }
        return (String[])filePaths.toArray(new String[filePaths.size()]);
    }

    /**
     * 创建指定的目录
     * @param basePath
     * @param relativePath
     * @param docId
     * @return
     */
    private static String getFilePath(String basePath,String relativePath,String docId){
        String filePath = null;
        try {
            StringBuilder pathBuilder = new StringBuilder();
            pathBuilder.append(basePath);
            pathBuilder.append("/");
            pathBuilder.append(relativePath);
//            pathBuilder.append("/");
//            pathBuilder.append(docId);
            filePath = StringUtil.replaceAll(StringUtil.replaceAll(pathBuilder.toString(),"\\","/"),".","/");
            FileUtils.forceMkdir(new File(filePath));
        }catch (IOException ie){
            LOGGER.error("目录创建失败 {}",filePath,ie);
        }
        return filePath;
    }

    public static String getDocumentHTMLUrl(String serverName, String dbPathName, DDocument dDocument) throws DominoException {
        Document document = (Document) dDocument.getBase();
        String  url = "";
        try {
            String s = new StringBuilder(dbPathName).append("/").append("0").append("/").append(document.getUniversalID()).toString();
           URI uri =  new URIBuilder().setScheme("http").setHost(serverName).setPath(s).setQuery("openDocument").build();
           url = uri.toString();
        } catch (NotesException e) {
            LOGGER.error("获取文档URL出错",e);
            throw new DominoException(e,DominoExceptionEnum.CREATE_URL_ERR);
        } catch (URISyntaxException e) {
            LOGGER.error("获取文档URL出错",e);
            throw new DominoException(e,DominoExceptionEnum.CREATE_URL_ERR);
        }finally {
            return url;
        }

    }
    public static String getDocumentFileName(DDocument dDocument) throws DominoException {
        try{
            String docId = getDocuemntId(dDocument);
            return String.format("%s.mht",docId);
        }catch (NotesException e){
            LOGGER.error("获取文档存储URL出错",e);
            throw new DominoException(e,DominoExceptionEnum.CREATE_URL_ERR);
        }
    }

    public static String getDocumentSavePath(String basePath, String dbPathName, DDocument dDocument) throws DominoException {
        try {
            String docId = getDocuemntId(dDocument);
            String filePath =  getFilePath(basePath, dbPathName, docId);
            return filePath;
        } catch (NotesException e) {
            LOGGER.error("获取文档存储URL出错",e);
            throw new DominoException(e,DominoExceptionEnum.CREATE_URL_ERR);
        }
    }

    public static void main(String[] args){


    }
}
